﻿using Abp.Application.Services.Dto;
using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.Organizations;
using Camc.Quality.Authorization.Roles;
using Camc.Quality.Authorization.Users;
using Camc.Quality.Dto;
using Camc.Quality.Inspection.InspectionManage;
using Camc.Quality.Inspection.InspectionReport;
using Camc.Quality.IOperationHistory;
using Camc.Quality.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Camc.Quality.Inspection
{
    public class InspectionReportAppService : QualityAppServiceBase
    {
            private readonly IRepository<InspectionSeverityDesc, Guid> _inspectionSeverityDescRepository;
            private readonly IRepository<InspectionSeverityRole, Guid> _inspectionSeverityRoleRepository;
            private readonly IRepository<InspectionTypeDesc, Guid> _inspectionTypeDescRepository;
            private readonly IRepository<InspectionItemInfo, Guid> _inspectionItemInfoRepository;
            private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;
            private readonly IRepository<InspectionStandardDesc, Guid> _inspectionStandardDescRepository;
            private readonly RoleManager _roleManager;
            private readonly IRepository<User, long> _userRepository;
            private readonly IRepository<UserRole, long> _userRoleRepository;
            private readonly ITempFileCacheManager _tempFileCacheManager;

        public InspectionReportAppService(IRepository<InspectionSeverityDesc, Guid> inspectionSeverityDescRepository,
                                 IRepository<InspectionSeverityRole, Guid> inspectionSeverityRoleRepository,
                                 IRepository<InspectionTypeDesc, Guid> inspectionTypeDescRepository,
                                 IRepository<InspectionItemInfo, Guid> inspectionItemInfoRepository,
                                 IRepository<OrganizationUnit, long> organizationUnitRepository,
                                 RoleManager roleManager,
                                 IRepository<InspectionStandardDesc, Guid> inspectionStandardDescRepository,
                                 IRepository<User, long> userRepository,
                                 IRepository<UserRole, long> UserRoleRepository,
                                 ITempFileCacheManager tempFileCacheManager
                                        )
            {
                _inspectionSeverityDescRepository = inspectionSeverityDescRepository;
                _inspectionSeverityRoleRepository = inspectionSeverityRoleRepository;
                _inspectionTypeDescRepository = inspectionTypeDescRepository;
                _inspectionItemInfoRepository = inspectionItemInfoRepository;
                _organizationUnitRepository = organizationUnitRepository;
                _roleManager = roleManager;
                _inspectionStandardDescRepository = inspectionStandardDescRepository;
                _userRepository = userRepository;
                _userRoleRepository = UserRoleRepository;
                _tempFileCacheManager = tempFileCacheManager;
        }
        /// <summary>
        /// 异常报表List
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<InspectionStandardDescOutDto>> GetInspectionStandardDescList(GetInspectionCheckInput input)
        {
            var userList = _userRepository.GetAll().ToList();
            var organizationUnitList = _organizationUnitRepository.GetAll().ToList();
            var rolesList = _roleManager.Roles.ToList();
            var inspectionStardardDesc = from inspectionStandardDesc in _inspectionStandardDescRepository.GetAll()
                                         join inspectionTypeDesc in _inspectionTypeDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionTypeDescId equals inspectionTypeDesc.Id
                                         join inspectionItemInfo in _inspectionItemInfoRepository.GetAll()
                                         on inspectionStandardDesc.InspectionItemInfoId equals inspectionItemInfo.Id
                                         join inspectionSeverityDesc in _inspectionSeverityDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionSeverityDescId equals inspectionSeverityDesc.Id
                                         join users in userList on inspectionStandardDesc.CreatorUserId equals users.Id
                                         //into ult
                                         //from a in ult.DefaultIfEmpty()
                                         join role in rolesList
                                         on inspectionItemInfo.RolesId equals role.Id into roled
                                         from rolet in roled.DefaultIfEmpty()
                                         join organizationUnit in organizationUnitList
                                         on inspectionItemInfo.OrganizationUnitsId equals organizationUnit.Id into organizationUnitd
                                         from organizationUnitt in organizationUnitd.DefaultIfEmpty()
                                         join userh in userList
                                         on inspectionStandardDesc.HandlerId equals userh.Id into userhd
                                         from userht in userhd.DefaultIfEmpty()
                                         join userc in userList
                                         on inspectionStandardDesc.ConfirmerId equals userc.Id into usercd
                                         from userct in usercd.DefaultIfEmpty()
                                         select new InspectionStandardDescOutDto
                                         {
                                             Id = inspectionStandardDesc.Id,
                                             Code = inspectionStandardDesc.Code,
                                             TaskCode = inspectionStandardDesc.TaskCode,
                                             InspectionTypeDescId = inspectionStandardDesc.InspectionTypeDescId,
                                             InspectionTypeDesc = inspectionTypeDesc.TypeName,
                                             InspectionItemInfoId = inspectionStandardDesc.InspectionItemInfoId,
                                             InspectionItemInfo = inspectionItemInfo.ItemName,
                                             InspectionDetails = inspectionStandardDesc.InspectionDetails,
                                             InspectionSeverityDescId = inspectionStandardDesc.InspectionSeverityDescId,
                                             InspectionSeverityDesc = inspectionSeverityDesc.SeverityName,
                                             State = (int)inspectionStandardDesc.State,
                                             Submitter = users.Surname + users.Name,
                                             CreatorUserId = inspectionStandardDesc.CreatorUserId,
                                             CreationTime = inspectionStandardDesc.CreationTime,
                                             Roles = rolet.DisplayName,
                                             RolesId = inspectionItemInfo.RolesId,
                                             OrganizationUnitsId = inspectionItemInfo.OrganizationUnitsId,
                                             OrganizationUnits = organizationUnitt.DisplayName,
                                             HandlerId = inspectionStandardDesc.HandlerId,
                                             Handler = userht.Surname + userht.Name,
                                             CompleteTime = inspectionStandardDesc.CompleteTime,
                                             CauseAnalysis = inspectionStandardDesc.CauseAnalysis,
                                             TreatmentMeasures = inspectionStandardDesc.TreatmentMeasures,
                                             RequestCompleteTime = inspectionStandardDesc.RequestCompleteTime,
                                             CostTime = inspectionStandardDesc.CostTime,
                                             ConfirmerId = inspectionStandardDesc.ConfirmerId,
                                             Confirmer = userct.Surname + userct.Name,
                                             ConfirmTime = inspectionStandardDesc.ConfirmTime,
                                             ConfirmSuggest = inspectionStandardDesc.ConfirmSuggest
                                         };
            if (input.StartDateTime != null && input.EndDateTime != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s =>s.CreationTime > input.StartDateTime && s.CreationTime.AddDays(-1) < input.EndDateTime);
            }
            else
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime > DateTime.Now.AddDays(-7));
            }
            var count = inspectionStardardDesc.Count();
            inspectionStardardDesc = inspectionStardardDesc.OrderByDescending(e => e.CreationTime).PageBy(input);
            var result = ObjectMapper.Map<List<InspectionStandardDescOutDto>>(inspectionStardardDesc);
            return new PagedResultDto<InspectionStandardDescOutDto>(count, result);
        }
        /// <summary>
        /// 异常报表记录导出
        /// </summary>
        /// <param name="startDateTime"></param>
        /// <param name="endDateTime"></param>
        /// <returns></returns>
        public async Task<string> GetInspectionStandardDescToExcel(DateTime? startDateTime, DateTime? endDateTime)
        {
            var userList = _userRepository.GetAll().ToList();
            var organizationUnitList = _organizationUnitRepository.GetAll().ToList();
            var rolesList = _roleManager.Roles.ToList();
            var inspectionStardardDesc = from inspectionStandardDesc in _inspectionStandardDescRepository.GetAll()
                                         join inspectionTypeDesc in _inspectionTypeDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionTypeDescId equals inspectionTypeDesc.Id
                                         join inspectionItemInfo in _inspectionItemInfoRepository.GetAll()
                                         on inspectionStandardDesc.InspectionItemInfoId equals inspectionItemInfo.Id
                                         join inspectionSeverityDesc in _inspectionSeverityDescRepository.GetAll()
                                         on inspectionStandardDesc.InspectionSeverityDescId equals inspectionSeverityDesc.Id
                                         join users in userList on inspectionStandardDesc.CreatorUserId equals users.Id
                                         //into ult
                                         //from a in ult.DefaultIfEmpty()
                                         join role in rolesList
                                         on inspectionItemInfo.RolesId equals role.Id into roled
                                         from rolet in roled.DefaultIfEmpty()
                                         join organizationUnit in organizationUnitList
                                         on inspectionItemInfo.OrganizationUnitsId equals organizationUnit.Id into organizationUnitd
                                         from organizationUnitt in organizationUnitd.DefaultIfEmpty()
                                         join userh in userList
                                         on inspectionStandardDesc.HandlerId equals userh.Id into userhd
                                         from userht in userhd.DefaultIfEmpty()
                                         join userc in userList
                                         on inspectionStandardDesc.ConfirmerId equals userc.Id into usercd
                                         from userct in usercd.DefaultIfEmpty()
                                         select new InspectionStandardDescOutDto
                                         {
                                             Id = inspectionStandardDesc.Id,
                                             Code = inspectionStandardDesc.Code,
                                             TaskCode = inspectionStandardDesc.TaskCode,
                                             InspectionTypeDescId = inspectionStandardDesc.InspectionTypeDescId,
                                             InspectionTypeDesc = inspectionTypeDesc.TypeName,
                                             InspectionItemInfoId = inspectionStandardDesc.InspectionItemInfoId,
                                             InspectionItemInfo = inspectionItemInfo.ItemName,
                                             InspectionDetails = inspectionStandardDesc.InspectionDetails,
                                             InspectionSeverityDescId = inspectionStandardDesc.InspectionSeverityDescId,
                                             InspectionSeverityDesc = inspectionSeverityDesc.SeverityName,
                                             State = (int)inspectionStandardDesc.State,
                                             Submitter = users.Surname + users.Name,
                                             CreatorUserId = inspectionStandardDesc.CreatorUserId,
                                             CreationTime = inspectionStandardDesc.CreationTime,
                                             Roles = rolet.DisplayName,
                                             RolesId = inspectionItemInfo.RolesId,
                                             OrganizationUnitsId = inspectionItemInfo.OrganizationUnitsId,
                                             OrganizationUnits = organizationUnitt.DisplayName,
                                             HandlerId = inspectionStandardDesc.HandlerId,
                                             Handler = userht.Surname + userht.Name,
                                             CompleteTime = inspectionStandardDesc.CompleteTime,
                                             CauseAnalysis = inspectionStandardDesc.CauseAnalysis,
                                             TreatmentMeasures = inspectionStandardDesc.TreatmentMeasures,
                                             RequestCompleteTime = inspectionStandardDesc.RequestCompleteTime,
                                             CostTime = inspectionStandardDesc.CostTime,
                                             ConfirmerId = inspectionStandardDesc.ConfirmerId,
                                             Confirmer = userct.Surname + userct.Name,
                                             ConfirmTime = inspectionStandardDesc.ConfirmTime,
                                             ConfirmSuggest = inspectionStandardDesc.ConfirmSuggest
                                         };
            if (startDateTime != null && endDateTime != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime.AddDays(1) > startDateTime && s.CreationTime.AddDays(-1) < endDateTime);
            }
            else
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime > DateTime.Now.AddDays(-7));
            }
            //var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll().Where(s => s.CreationTime > startDateTime.AddDays(-1) && s.CreationTime < endDateTime.AddDays(1)).OrderByDescending(e => e.CreationTime);
            var result = ObjectMapper.Map<List<InspectionStandardDescOutDto>>(inspectionStardardDesc);
            InspectionExportAppService service = new InspectionExportAppService(_tempFileCacheManager);
            return service.ExportToFile(result);
        }


        /// <summary>
        /// 柱形图数据统计
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public InspectionReportDataOutDto GetInepectionReportDataCollection(GetInspectionReportInput input)
        {
            List<InspectionReportDataDto> inspectionReportDataDtos = new List<InspectionReportDataDto>();
            InspectionReportDataOutDto inspectionReportDataOutDto = new InspectionReportDataOutDto();
            //var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll().Where(s => s.CreationTime > input.StartDateTime.AddDays(-1) && s.CreationTime < input.EndDateTime.AddDays(1));
            var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll();
            if (input.StartDateTime != null && input.EndDateTime != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime.AddDays(1) > input.StartDateTime && s.CreationTime.AddDays(-1) < input.EndDateTime);
            }
            else
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime > DateTime.Now.AddDays(-7));
            }
            var inspectionStardardDescList = from isd in inspectionStardardDesc
                                             join it in _inspectionTypeDescRepository.GetAll()
                                             on isd.InspectionTypeDescId equals it.Id
                                             join ii in _inspectionItemInfoRepository.GetAll()
                                             on isd.InspectionItemInfoId equals ii.Id
                                             join isdd in _inspectionSeverityDescRepository.GetAll()
                                             on isd.InspectionSeverityDescId equals isdd.Id

                                             select new InspectionReportListDto
                                             {
                                                 InspectionTypeDesc = it.TypeName,
                                                 InspectionTypeDescId = isd.InspectionTypeDescId,
                                                 InspectionItemInfo = ii.ItemName,
                                                 InspectionItemInfoId = isd.InspectionItemInfoId,
                                                 InspectionSeverityDesc = isdd.SeverityName,
                                                 InspectionSeverityDescId = isd.InspectionSeverityDescId,
                                                 Day = isd.CreationTime.ToString("yyMMdd"),
                                                 Week = (DateTime.Parse(isd.CreationTime.ToString()).DayOfYear / 7 + 1).ToString(),
                                                 Month = isd.CreationTime.ToString("yyMM"),
                                             };
            ///时间维度 0:按日 1:按周 2:按年
            if (input.TimeDimension == 0)
            {
                ///统计维度 0:责任部门 1:一级异常 2:二级异常
                if (input.StatisticalDimension == 1)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Day = a.Day, InspectionItemInfoId = a.InspectionItemInfoId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionTypeDesc,
                            Time = s.First().Day,
                            Count = s.Count()
                        }).ToList();
                }
                if (input.StatisticalDimension == 2)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Day = a.Day, InspectionItemInfoId = a.InspectionItemInfoId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionItemInfo,
                            Time = s.First().Day,
                            Count = s.Count()
                        }).ToList();
                }
                if (input.StatisticalDimension == 0)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Day = a.Day, InspectionSeverityDescId = a.InspectionSeverityDescId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionSeverityDesc,
                            Time = s.First().Day,
                            Count = s.Count()
                        }).ToList();
                }
            }
            if (input.TimeDimension == 1)
            {
                if (input.StatisticalDimension == 1)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Week = a.Week, InspectionItemInfoId = a.InspectionItemInfoId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionTypeDesc,
                            Time = s.First().Week,
                            Count = s.Count()
                        }).ToList();
                }
                if (input.StatisticalDimension == 2)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Week = a.Week, InspectionItemInfoId = a.InspectionItemInfoId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionItemInfo,
                            Time = s.First().Week,
                            Count = s.Count()
                        }).ToList();
                }
                if (input.StatisticalDimension == 0)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Week = a.Week, InspectionSeverityDescId = a.InspectionSeverityDescId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionSeverityDesc,
                            Time = s.First().Week,
                            Count = s.Count()
                        }).ToList();
                }
            }
            if (input.TimeDimension == 2)
            {
                if (input.StatisticalDimension == 1)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Month = a.Month, InspectionSeverityDescId = a.InspectionSeverityDescId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionSeverityDesc,
                            Time = s.First().Month,
                            Count = s.Count()
                        }).ToList();
                }
                if (input.StatisticalDimension == 2)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Month = a.Month, InspectionSeverityDescId = a.InspectionSeverityDescId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionSeverityDesc,
                            Time = s.First().Month,
                            Count = s.Count()
                        }).ToList();
                }
                if (input.StatisticalDimension == 0)
                {
                    inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { Month = a.Month, InspectionSeverityDescId = a.InspectionSeverityDescId })
                        .Select(s => new InspectionReportDataDto
                        {
                            Name = s.First().InspectionSeverityDesc,
                            Time = s.First().Month,
                            Count = s.Count()
                        }).ToList();
                }
            }
            List<string> name = new List<string>();
            List<string> time = new List<string>();
            List<int> count = new List<int>();
            name.AddRange(inspectionReportDataDtos.Select(d => d.Name).ToArray());
            time.AddRange(inspectionReportDataDtos.Select(d => d.Time).ToArray());
            count.AddRange(inspectionReportDataDtos.Select(d => d.Count).ToArray());
            inspectionReportDataOutDto.Name = name;
            inspectionReportDataOutDto.Time = time;
            inspectionReportDataOutDto.Count = count;
            return inspectionReportDataOutDto;
        }
        /// <summary>
        /// 扇形图数据统计
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public InspectionReportDataOutDto GetInepectionReportDataSector(GetInspectionReportInput input)
        {
            List<InspectionReportDataDto> inspectionReportDataDtos = new List<InspectionReportDataDto>();
            InspectionReportDataOutDto inspectionReportDataOutDto = new InspectionReportDataOutDto();
            //var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll().Where(s => s.CreationTime > input.StartDateTime.AddDays(-1) && s.CreationTime < input.EndDateTime.AddDays(1));
            var inspectionStardardDesc = _inspectionStandardDescRepository.GetAll();
            if (input.StartDateTime != null && input.EndDateTime != null)
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime.AddDays(1) > input.StartDateTime && s.CreationTime.AddDays(-1) < input.EndDateTime);
            }
            else
            {
                inspectionStardardDesc = inspectionStardardDesc.Where(s => s.CreationTime > DateTime.Now.AddDays(-7));
            }
            var inspectionStardardDescList = from isd in inspectionStardardDesc
                                             join it in _inspectionTypeDescRepository.GetAll()
                                             on isd.InspectionTypeDescId equals it.Id
                                             join ii in _inspectionItemInfoRepository.GetAll()
                                             on isd.InspectionItemInfoId equals ii.Id
                                             join isdd in _inspectionSeverityDescRepository.GetAll()
                                             on isd.InspectionSeverityDescId equals isdd.Id

                                             select new InspectionReportListDto
                                             {
                                                 InspectionTypeDesc = it.TypeName,
                                                 InspectionTypeDescId = isd.InspectionTypeDescId,
                                                 InspectionItemInfo = ii.ItemName,
                                                 InspectionItemInfoId = isd.InspectionItemInfoId,
                                                 InspectionSeverityDesc = isdd.SeverityName,
                                                 InspectionSeverityDescId = isd.InspectionSeverityDescId,
                                             };
            ///统计维度 0:责任部门 1:一级异常 2:二级异常
            if (input.StatisticalDimension == 1)
            {
                inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new {InspectionItemInfoId = a.InspectionItemInfoId })
                       .Select(s => new InspectionReportDataDto
                       {
                           Name = s.First().InspectionItemInfo,
                           Count = s.Count()
                       }).ToList();
            }
            if (input.StatisticalDimension == 2)
            {
                inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new {InspectionItemInfoId = a.InspectionItemInfoId })
                      .Select(s => new InspectionReportDataDto
                      {
                          Name = s.First().InspectionItemInfo,
                          Count = s.Count()
                      }).ToList();
            }
            if (input.StatisticalDimension == 0)
            {
                inspectionReportDataDtos = inspectionStardardDescList.GroupBy(a => new { InspectionSeverityDescId = a.InspectionSeverityDescId })
                    .Select(s => new InspectionReportDataDto
                    {
                        Name = s.First().InspectionItemInfo,
                    }).ToList();
            }
            List<string> name = new List<string>();
            List<int> count = new List<int>();
            name.AddRange(inspectionReportDataDtos.Select(d => d.Name).ToArray());
            count.AddRange(inspectionReportDataDtos.Select(d => d.Count).ToArray());
            inspectionReportDataOutDto.Name = name;
            inspectionReportDataOutDto.Count = count;
            return inspectionReportDataOutDto;
        }
    }
}
